#include "StdAfx.h"
#include "SceneViewForm.h"
#include "Mainform.h"

using namespace OgreUnified;

SceneViewForm::SceneViewForm(int id, SceneManager* sceneMgr)
{
	InitializeComponent();
	
	mCtrl = mShift = mAlt = mMiddleButton = mLeftButton = mRightButton = false;

	HWND hWnd = (HWND) (void*) mPictureBox->Handle.ToPointer();
	NameValuePairList misc;
	misc["externalWindowHandle"] = Ogre::StringConverter::toString((int)hWnd);
	
	Ogre::String camName = "SceneView::Camera" + Ogre::StringConverter::toString(id);

	mRenderWin = Ogre::Root::getSingletonPtr()->createRenderWindow(camName, 800, 600, false, &misc);
	mSceneMgr = sceneMgr;//OgreInit::getSingletonPtr()->getSceneMgr();
	//mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
	mCamera = mSceneMgr->createCamera(camName);
	//DeleteHGlobalAnsi(camName);

	
	mViewport = mRenderWin->addViewport(mCamera);
	mViewport->setBackgroundColour(Ogre::ColourValue::White);
	mViewport->setAutoUpdated(true);

	mCamera->setAutoAspectRatio(true);

	mViewportGrid = new ViewportGrid(mSceneMgr, mViewport);
	mViewportGrid->enable();
	mViewportGrid->setColour(ColourValue(0.33,0.33,0.33));
	
//	mCamera->setProjectionType(Ogre::ProjectionType::PT_ORTHOGRAPHIC);
	mCamera->setFarClipDistance(0);
	mCamera->setNearClipDistance(1);
	mCamera->setPosition(Vector3(0,100,0));
	//mCamera->lookAt(Vector3(0,0,0));

	mCamSpeed = 1;

	mAxis = EditorAxis::getInstance();
	mAxis->init(mSceneMgr);
	/*---------Events handlers-------------------------------------------------------------*/
	mPictureBox->MouseEnter	+= gcnew EventHandler(this, &SceneViewForm::On_MouseEnter);
	mPictureBox->MouseLeave	+= gcnew EventHandler(this, &SceneViewForm::On_MouseLeave);

	mPictureBox->MouseClick	+= gcnew MouseEventHandler(this, &SceneViewForm::On_MouseClick);
	mPictureBox->MouseDoubleClick+= gcnew MouseEventHandler(this, &SceneViewForm::On_MouseDoubleClick);
	mPictureBox->MouseDown	+= gcnew MouseEventHandler(this, &SceneViewForm::On_MouseDown);
	mPictureBox->MouseUp	+= gcnew MouseEventHandler(this, &SceneViewForm::On_MouseUp);
	
	MouseWheel	+= gcnew MouseEventHandler(this, &SceneViewForm::On_MouseWheel);
	mPictureBox->MouseMove	+= gcnew MouseEventHandler(this, &SceneViewForm::On_MouseMove);

	KeyDown	 += gcnew KeyEventHandler(this, &SceneViewForm::On_KeyDown);
	KeyUp	 += gcnew KeyEventHandler(this, &SceneViewForm::On_KeyUp);
	KeyPress += gcnew KeyPressEventHandler(this, &SceneViewForm::On_KeyPressed);
}

SceneViewForm::~SceneViewForm()
{
	mRenderWin->removeAllViewports();
	mRenderWin->destroy();
	
	if (components)
	{
		delete components;
	}
}

void SceneViewForm::update()
{

}

void SceneViewForm::On_KeyDown(Object^ sender, KeyEventArgs^ e)
{
	//mRenderWin->writeContentsToFile("Test.jpg");
	mAlt = e->Alt;
	mCtrl = e->Control;
	mShift = e->Shift;

}

void SceneViewForm::On_KeyUp(Object^ sender, KeyEventArgs^ e)
{
	mAlt = e->Alt;
	mCtrl = e->Control;
	mShift = e->Shift;

}

void SceneViewForm::On_KeyPressed(Object^ sender, KeyPressEventArgs^ e)
{
	char c = System::Char::ToLower(e->KeyChar);
	if(mRightButton)
	{
		if(c == 'w' )
		{
			mCamera->moveRelative(Vector3(0,0,-mCamSpeed));
		}
		if(c == 'a' )
		{
			mCamera->moveRelative(Vector3(-mCamSpeed,0,0));
		}
		if(c == 's' )
		{
			mCamera->moveRelative(Vector3(0,0,mCamSpeed));
		}
		if(c == 'd' )
		{
			mCamera->moveRelative(Vector3(mCamSpeed,0,0));
		}
		if(c == 'q' )
		{
			mCamera->moveRelative(Vector3(0,-mCamSpeed,0));
		}
		if(c == 'e' )
		{
			mCamera->moveRelative(Vector3(0, mCamSpeed,0));
		}
	}

	//Root::getSingletonPtr()->renderOneFrame();

}

void SceneViewForm::On_MouseEnter(Object^ sender, EventArgs^ e)
{
	//mViewport->setBackgroundColour(Ogre::ColourValue::Red);
}

void SceneViewForm::On_MouseLeave(Object^ sender, EventArgs^ e)
{

}

void SceneViewForm::On_MouseMove(Object^ sender, MouseEventArgs^ e)
{
	//gizmos raycast
	//mAxis
	//entity raycast
	Ogre::Ray ray= mCamera->getCameraToViewportRay( (float)e->Location.X/(float)Width, (float)e->Location.Y/(float)Height);
	m_pray_scene_query = mSceneMgr->createRayQuery(ray,Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK);
	m_pray_scene_query->setSortByDistance(true);
	Vector3 result;
	Entity* entity;
	if(OgreInterface::getSingletonPtr()->RaycastFromPoint(m_pray_scene_query, ray.getOrigin(), ray.getDirection(), result, *entity))
	{
		ConsoleForm::Instance->logMessage("n");
		ConsoleForm::Instance->logMessage(entity->getName());
	}

	if(mLeftButton && mRightButton)//e->Button == System::Windows::Forms::MouseButtons::Right && e->Button == System::Windows::Forms::MouseButtons::Left)
	{

	}
	else if(mRightButton)//e->Button == System::Windows::Forms::MouseButtons::Right)
	{
		Point diff = Point(mPrevMousePos.X - e->Location.X, mPrevMousePos.Y - e->Location.Y);
		mCamera->yaw(Degree(diff.X));
		mCamera->pitch(Degree(diff.Y));
		mPrevMousePos = e->Location;
	}
	else if(mLeftButton)
	{

	}
}

void SceneViewForm::On_MouseClick(Object^ sender, MouseEventArgs^ e)
{

}

void SceneViewForm::On_MouseDown(Object^ sender, MouseEventArgs^ e)
{
	mLeftButton = (e->Button == System::Windows::Forms::MouseButtons::Left);
	mRightButton = (e->Button == System::Windows::Forms::MouseButtons::Right);
	mMiddleButton = (e->Button == System::Windows::Forms::MouseButtons::Middle);
	
	mPrevMousePos = e->Location;
}

void SceneViewForm::On_MouseUp(Object^ sender, MouseEventArgs^ e)
{
	mLeftButton = !(e->Button == System::Windows::Forms::MouseButtons::Left);
	mRightButton = !(e->Button == System::Windows::Forms::MouseButtons::Right);
	mMiddleButton = !(e->Button == System::Windows::Forms::MouseButtons::Middle);

	/*if(e->Button == System::Windows::Forms::MouseButtons::Left)
		mLeftButton = false;
	if(e->Button == System::Windows::Forms::MouseButtons::Right)
		mRightButton =	false;
	if(e->Button == System::Windows::Forms::MouseButtons::Middle)
		mMiddleButton = false;*/
}

void SceneViewForm::On_MouseWheel(Object^ sender, MouseEventArgs^ e)
{
//	Root::getSingletonPtr()->renderOneFrame();
	mCamera->moveRelative(Vector3(0,0,-e->Delta/2));
}

void SceneViewForm::On_MouseDoubleClick(Object^ sender, MouseEventArgs^ e)
{

}

void SceneViewForm::InitializeComponent(void)
{
	this->mPictureBox = (gcnew System::Windows::Forms::PictureBox());
	(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->mPictureBox))->BeginInit();
	this->SuspendLayout();
	// 
	// mPictureBox
	// 
	this->mPictureBox->BackColor = System::Drawing::SystemColors::ActiveCaptionText;
	this->mPictureBox->Dock = System::Windows::Forms::DockStyle::Fill;
	this->mPictureBox->Location = System::Drawing::Point(0, 0);
	this->mPictureBox->Name = L"mPictureBox";
	this->mPictureBox->Size = System::Drawing::Size(284, 262);
	this->mPictureBox->TabIndex = 0;
	this->mPictureBox->TabStop = false;
	// 
	// SceneViewForm
	// 
	this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
	this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
	this->ClientSize = System::Drawing::Size(284, 262);
	this->Controls->Add(this->mPictureBox);
	this->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
		static_cast<System::Byte>(0)));
	this->Name = L"SceneViewForm";
	this->Text = L"SceneViewForm";
	(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->mPictureBox))->EndInit();
	this->ResumeLayout(false);

}